//
// Created by Administrator on 2024/7/10.
//

#ifndef JTT809_HEADER_H
#define JTT809_HEADER_H
#include <cstdint>
#include "util/utils.h"

#include "jtt809_body.h"
#include "interfaces/base.h"
#include "util/constants.h"
#include "util/macros.h"

namespace protocol {
    class MessagePackReader;
    class MessagePackWriter;

    class JTT809Header : public Serializable, public Sizeable {
        uint32_t msgLength;
        uint32_t msgSN;
        uint16_t msgId;
        uint32_t msgGnsscenterId;
        uint8_t versionFlag[3]{};
        uint8_t encryptFlag;
        uint32_t encryptKey;
        time_t time;
        IMPLEMENT_SIZEABLE(msgLength, msgSN, msgId, msgGnsscenterId, versionFlag, encryptFlag, encryptKey, time)

    public:
        friend void check_attribute();

        JTT809Header() = default;

        JTT809Header(const JTT809Body &body, const uint32_t msg_sn, const uint16_t msg_id,
                     const uint32_t msg_gnsscenter_id, const byte *const version_flag, const byte encrypt_flag,
                     const uint32_t encrypt_key, const time_t time)
            : msgLength(size(body)+NO_BODY_LENGTH),
              msgSN(msg_sn),
              msgId(msg_id),
              msgGnsscenterId(msg_gnsscenter_id),
              encryptFlag(encrypt_flag),
              encryptKey(encrypt_key),
              time(time) {
            memcpy(this->versionFlag, version_flag, 3);
        }

        JTT809Header(const JTT809Header &other) = default;

        JTT809Header &operator=(const JTT809Header &other) = default;

        bool tryGetEncryptKey(uint32_t &key) const;

        void serialize(MessagePackWriter &writer) override;

        void deserialize(MessagePackReader &reader) override;

        [[nodiscard]] uint32_t get_msg_length() const {
            return msgLength;
        }

        [[nodiscard]] uint32_t get_msg_sn() const {
            return msgSN;
        }

        [[nodiscard]] uint16_t get_msg_id() const {
            return msgId;
        }

        [[nodiscard]] uint32_t get_msg_gnsscenter_id() const {
            return msgGnsscenterId;
        }

        [[nodiscard]] byte get_encrypt_flag() const {
            return encryptFlag;
        }

        [[nodiscard]] uint32_t get_encrypt_key() const {
            return encryptKey;
        }

        [[nodiscard]] time_t get_time() const {
            return time;
        }

        ~JTT809Header() = default;
    };
}


#endif //JTT809_HEADER_H
